//go:build windows

package webport_web

import (
	"fmt"
	"runtime"

	"github.com/gin-gonic/gin"
	"golang.org/x/sys/windows/registry"
)

func getWindowsRegistryKey(name string) (key registry.Key, err error) {
	switch name {
	case "HKEY_CLASSES_ROOT":
		key = registry.CLASSES_ROOT
	case "HKEY_CURRENT_CONFIG":
		key = registry.CURRENT_CONFIG
	case "HKEY_CURRENT_USER":
		key = registry.CURRENT_USER
	case "HKEY_LOCAL_MACHINE":
		key = registry.LOCAL_MACHINE
	case "HKEY_PERFORMANCE_DATA":
		key = registry.PERFORMANCE_DATA
	case "HKEY_USERS":
		key = registry.USERS
	default:
		err = fmt.Errorf("invalid registry key name: %s", name)
	}

	return
}

func readWindowsRegistryString(key_name string, path string, name string) (val string, err error) {
	key, err := getWindowsRegistryKey(key_name)
	if err != nil {
		return
	}

	k, err := registry.OpenKey(key, path, registry.QUERY_VALUE)
	if err != nil {
		return
	}
	defer k.Close()

	val, _, err = k.GetStringValue(name)
	if err != nil {
		return
	}

	return
}

func readWindowsRegistryBinary(key_name string, path string, name string) (val []byte, err error) {
	key, err := getWindowsRegistryKey(key_name)
	if err != nil {
		return
	}

	k, err := registry.OpenKey(key, path, registry.QUERY_VALUE)
	if err != nil {
		return
	}
	defer k.Close()

	val, _, err = k.GetBinaryValue(name)
	if err != nil {
		return
	}

	return
}

func readWindowsRegistryInteger(key_name string, path string, name string) (val uint64, err error) {
	key, err := getWindowsRegistryKey(key_name)
	if err != nil {
		return
	}

	k, err := registry.OpenKey(key, path, registry.QUERY_VALUE)
	if err != nil {
		return
	}
	defer k.Close()

	val, _, err = k.GetIntegerValue(name)
	if err != nil {
		return
	}

	return
}

// Read the Windows registry.
// GET /api/windows/registry
// query参数:
//   - root: 注册表的根节点, 例如：
//     "HKEY_CLASSES_ROOT"
//     "HKEY_CURRENT_CONFIG"
//     "HKEY_CURRENT_USER"
//     "HKEY_LOCAL_MACHINE"
//     "HKEY_PERFORMANCE_DATA"
//     "HKEY_USERS"
//   - path: 键的路径， 例如: "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
//   - key: 键的名称，例如: "SystemRoot"
//   - type: 键的类型，例如: "string", "binary", "integer"
func handleWindowsRegistry(c *gin.Context) {
	root := c.DefaultQuery("root", "")
	if root == "" {
		sendError(c, 400, "root is empty")
		return
	}

	path := c.DefaultQuery("path", "")
	if path == "" {
		sendError(c, 400, "path is empty")
		return
	}

	key := c.DefaultQuery("key", "")
	if path == "" {
		sendError(c, 400, "key is empty")
		return
	}

	keyType := c.DefaultQuery("type", "")
	if keyType == "" {
		sendError(c, 400, "type is empty")
		return
	}

	// check if Windows
	if runtime.GOOS != "windows" {
		sendError(c, 500, "unsupported system")
		return
	}

	if keyType == "string" {
		val, err := readWindowsRegistryString(root, path, key)
		if err != nil {
			sendError(c, 500, err.Error())
		} else {
			sendResult(c, 200, val)
		}
	} else if keyType == "binary" {
		val, err := readWindowsRegistryBinary(root, path, key)
		if err != nil {
			sendError(c, 500, err.Error())
		} else {
			sendResult(c, 200, val)
		}
	} else if keyType == "integer" {
		val, err := readWindowsRegistryInteger(root, path, key)
		if err != nil {
			sendError(c, 500, err.Error())
		} else {
			sendResult(c, 200, val)
		}
	} else {
		sendResult(c, 400, "unsupported key type")
	}
}
